﻿/*---------------------------------------------------------------------------
    ZaRan	-	A Totallly Automatic CFD Software
    Copyright (C) ,Since 2020
-------------------------------------------------------------------------------
License
    This file is part of ZaRan.

!	@file		gird.h
!	@brief	the purpose of this file.
!	@author	Chen Jie.
\*---------------------------------------------------------------------------*/
#include<iostream>
#include "../include/Coordtrans.h"
void CoordTrans::CoordTransNoTime2D(Point xRight, Point xLeft, Point yRight, Point yLeft)
{
  //xξ yξ zξ tξ
  coef_[0] = 0.5 * (xRight.x() - xLeft.x());
  coef_[1] = 0.5 * (xRight.y() - xLeft.y());
  coef_[2] = 0;
  coef_[3] = 0;

  //xη yη zη tη,
  coef_[4] = 0.5 * (yRight.x() - yLeft.x());
  coef_[5] = 0.5 * (yRight.y() - yLeft.y());
  coef_[6] = 0;
  coef_[7] = 0;
  //    |x_xi   x_eta|
  // J= |            |
  //    |y_xi   y_eta|
  jacob_ = x_xi() * y_eta() - x_eta() * y_xi();
  jacob_ = 1.0 / jacob_;

  //ξx ηx ζx τx,
  coef_[16] = jacob_ * y_eta();
  coef_[17] = -jacob_ * y_xi();
  coef_[18] = 0;
  coef_[19] = 0;

  //ξy ηy ζy τy,
  coef_[20] = -jacob_ * x_eta();
  coef_[21] = jacob_ * x_xi();
  coef_[22] = 0;
  coef_[23] = 0;

  //ξz ηz ζz τz,
  coef_[24] = 0;
  coef_[25] = 0;
  coef_[26] = 0;
  coef_[27] = 0;

  //xτ yτ zτ tτ,
  coef_[12] = 0;
  coef_[13] = 0;
  coef_[14] = 0;
  coef_[15] = 1;
  //ξt ηt ζt τt,
  coef_[28] = 0;
  coef_[29] = 0;
  coef_[30] = 0;
  coef_[31] = 1;

}
void CoordTrans::CoordTransNoTime3D(Point xRight, Point xLeft, Point yRight, Point yLeft, Point zRight, Point zLeft)
{
  //xξ yξ zξ tξ
  coef_[0] = 0.5 * (xRight.x() - xLeft.x());
  coef_[1] = 0.5 * (xRight.y() - xLeft.y());
  coef_[2] = 0.5 * (xRight.z() - xLeft.z());
  coef_[3] = 0;

  //xη yη zη tη,
  coef_[4] = 0.5 * (yRight.x() - yLeft.x());
  coef_[5] = 0.5 * (yRight.y() - yLeft.y());
  coef_[6] = 0.5 * (yRight.z() - yLeft.z());
  coef_[7] = 0;

  //xζ yζ zζ tζ,
  coef_[8] = 0.5 * (zRight.x() - zLeft.x());
  coef_[9] = 0.5 * (zRight.y() - zLeft.y());
  coef_[10] = 0.5 * (zRight.z() - zLeft.z());
  coef_[11] = 0;

  //J
  jacob_ = x_xi() * (y_eta() * z_zeta() - y_zeta() * z_eta())
    - x_eta() * (y_xi() * z_zeta() - y_zeta() * z_xi())
    + x_zeta() * (y_xi() * z_eta() - y_eta() * z_xi());
  jacob_ = 1.0 / jacob_;

  //ξx ηx ζx τx,
  coef_[16] = jacob_ * (y_eta() * z_zeta() - y_zeta() * z_eta());
  coef_[17] = jacob_ * (y_zeta() * z_xi() - y_xi() * z_zeta());
  coef_[18] = jacob_ * (y_xi() * z_eta() - y_eta() * z_xi());
  coef_[19] = 0;

  //ξy ηy ζy τy,
  coef_[20] = jacob_ * (x_zeta() * z_eta() - x_eta() * z_zeta());
  coef_[21] = jacob_ * (x_xi() * z_zeta() - x_zeta() * z_xi());
  coef_[22] = jacob_ * (x_eta() * z_xi() - x_xi() * z_eta());
  coef_[23] = 0;

  //ξz ηz ζz τz,
  coef_[24] = jacob_ * (x_eta() * y_zeta() - x_zeta() * y_eta());
  coef_[25] = jacob_ * (x_zeta() * y_xi() - x_xi() * y_zeta());
  coef_[26] = jacob_ * (x_xi() * y_eta() - x_eta() * y_xi());
  coef_[27] = 0;

  //xτ yτ zτ tτ,
  coef_[12] = 0;
  coef_[13] = 0;
  coef_[14] = 0;
  coef_[15] = 1;
  //ξt ηt ζt τt,
  coef_[28] = -(x_tau() * xi_x() + y_tau() * xi_y() + z_tau() * xi_z());
  coef_[29] = -(x_tau() * eta_x() + y_tau() * eta_y() + z_tau() * eta_z());
  coef_[30] = -(x_tau() * zeta_x() + y_tau() * zeta_y() + z_tau() * zeta_z());
  coef_[31] = 1;

}
void CoordTrans::CoordTransTime2D(double dt, Point tRight, Point tLeft, Point xRight, Point xLeft, Point yRight, Point yLeft)
{
  CoordTransNoTime2D(xRight, xLeft, yRight, yLeft);
  //xτ yτ zτ tτ,
  coef_[12] = (tRight.x() - tLeft.x()) / dt;
  coef_[13] = (tRight.y() - tLeft.y()) / dt;
  coef_[14] = 0;
  coef_[15] = 1;
  //ξt ηt ζt τt,
  coef_[28] = -(x_tau() * xi_x() + y_tau() * xi_y() + z_tau() * xi_z());
  coef_[29] = -(x_tau() * eta_x() + y_tau() * eta_y() + z_tau() * eta_z());
  coef_[30] = -(x_tau() * zeta_x() + y_tau() * zeta_y() + z_tau() * zeta_z());
  coef_[31] = 1;

}
void CoordTrans::CoordTransTime3D(double dt, Point tRight, Point tLeft, Point xRight, Point xLeft, Point yRight, Point yLeft, Point zRight, Point zLeft)
{
  CoordTransNoTime3D(xRight, xLeft, yRight, yLeft, zRight, zLeft);
  //xτ yτ zτ tτ,
  coef_[12] = (tRight.x() - tLeft.x()) / dt;
  coef_[13] = (tRight.y() - tLeft.y()) / dt;
  coef_[14] = (tRight.z() - tLeft.z()) / dt;
  coef_[15] = 1;
  //ξt ηt ζt τt,
  coef_[28] = -(x_tau() * xi_x() + y_tau() * xi_y() + z_tau() * xi_z());
  coef_[29] = -(x_tau() * eta_x() + y_tau() * eta_y() + z_tau() * eta_z());
  coef_[30] = -(x_tau() * zeta_x() + y_tau() * zeta_y() + z_tau() * zeta_z());
  coef_[31] = 1;

}

CoordTrans::CoordTrans(int dim, double dt, Point tRight, Point tLeft, Point xRight, Point xLeft, Point yRight, Point yLeft)
{
  coef_.resize(32);
  jacob_ = 0;
  dimension_ = dim;
  if (dim == 2)
    CoordTransTime2D(dimension_, tRight, tLeft, xRight, xLeft, yRight, yLeft);
  else
    exit(0);
}

CoordTrans::CoordTrans(int dim, double dt, Point tRight, Point tLeft, Point xRight, Point xLeft, Point yRight, Point yLeft, Point zRight, Point zLeft)
{  //未加动网格 2020.07.31
  coef_.resize(32);
  jacob_ = 0;
  dimension_ = dim;
  if (dim == 3)
    CoordTransTime3D(dt, tRight, tLeft, xRight, xLeft, yRight, yLeft, zRight, zLeft);
  else
    exit(0);
}

CoordTrans::CoordTrans(int dim, Point xRight, Point xLeft, Point yRight, Point yLeft)
{
  coef_.resize(32);
  jacob_ = 0;
  dimension_ = dim;
  if (dim == 2)
    CoordTransNoTime2D(xRight, xLeft, yRight, yLeft);
  else
    exit(0);

}

CoordTrans::CoordTrans(int dim, Point xRight, Point xLeft, Point yRight, Point yLeft, Point zRight, Point zLeft)
{
  coef_.resize(32);
  jacob_ = 0;
  dimension_ = dim;
  if (dim == 3)
    CoordTransNoTime3D(xRight, xLeft, yRight, yLeft, zRight, zLeft);
  else
    exit(0);

}

CoordTrans::CoordTrans(int dim, const vector<Point>& coord_neib)
{
  coef_.resize(32);
  jacob_ = 0;
  dimension_ = dim;
  if (dimension_ == 2 && coord_neib.size() == 4)//二维
    CoordTransNoTime2D(coord_neib[0], coord_neib[2], coord_neib[1], coord_neib[3]);
  else if (dimension_ == 3 && coord_neib.size() == 6)//三维
  {
    CoordTransNoTime3D(coord_neib[0], coord_neib[2], coord_neib[1], coord_neib[3], coord_neib[4], coord_neib[5]);
  }
  else//意外情况
  {
    std::cout << "wrong neibor num = " << coord_neib.size() << std::endl;
    exit(0);
  }
}